
/*
 * File:   pipeline_data_structure_tests.cpp
 * Author: picci
 *
 * Created on Oct 30, 2010, 11:26:40 AM
 */

#define BOOST_TEST_MODULE pipeline data structures test
#include <boost/test/included/unit_test.hpp>

#include <cv.h>

#include "prj_definitions.h"
#include "generators/cameraInputGenerator.h"
#include "pipeline/pipeline_io.h"
#include "pipeline/pipeline_data_structures.h"
#include "common/utility_data_structures.h"

#include "imgops/filters/GaussBlurOp.h"

struct pipeline_data_structures_fixture{
    pipeline_data_structures_fixture(){
        copy_gbo = 0; assigned_gbo = 0;
        gbo = new NAMESPACE::GaussBlurOp();

        // input set
        cig = new NAMESPACE::CameraInputGenerator();
        cig->open();
        cig->set_key(gbo->getInputKeysList().at(0));        
        inputs = new std::list<NAMESPACE::pipe_input_t>();

        // criteria set
        io_width =  new NAMESPACE::NumericIOElement(5);
        io_width->setIOKey(gbo->getCriteriaKeysList().at(0));
        io_height = new NAMESPACE::NumericIOElement(5);
        io_height->setIOKey(gbo->getCriteriaKeysList().at(1));
        io_sigmaX = new NAMESPACE::NumericIOElement(1.0);
        io_sigmaX->setIOKey(gbo->getCriteriaKeysList().at(2));
                
        criteria = new std::list<NAMESPACE::pipe_criteria_t>();

        // output set
        out_img = new cv::Mat();
        io_out_img = new NAMESPACE::GenericIOElement();
        any_out_img = new boost::any(out_img);
        io_out_img->setElement(any_out_img);
        io_out_img->setIOKey(gbo->getOutputKeysList().at(0));

        outputs = new std::list<NAMESPACE::pipe_output_t>();
    }

    ~pipeline_data_structures_fixture(){
        delete cig;
        if(gbo)delete gbo;
        if(copy_gbo)delete copy_gbo;
        if(assigned_gbo)delete assigned_gbo;

        delete any_out_img;
        delete out_img;
        delete io_out_img;
        delete io_width;
        delete io_height;
        delete io_sigmaX;

        delete inputs;
        delete outputs;
        delete criteria;
    }

    NAMESPACE::CameraInputGenerator *cig;
    NAMESPACE::GaussBlurOp *gbo, *copy_gbo, *assigned_gbo;

    cv::Mat* out_img;
    boost::any* any_out_img;
    NAMESPACE::IOElement* io_out_img;
    NAMESPACE::IOElement* io_width;
    NAMESPACE::IOElement* io_height;
    NAMESPACE::IOElement* io_sigmaX;

    std::list<NAMESPACE::pipe_input_t>* inputs;
    std::list<NAMESPACE::pipe_criteria_t>* criteria;
    std::list<NAMESPACE::pipe_output_t>* outputs;
};

BOOST_FIXTURE_TEST_SUITE(pipeline_data_structures_test, pipeline_data_structures_fixture)

BOOST_AUTO_TEST_SUITE(AbstractOperation_test)

BOOST_AUTO_TEST_CASE(AbstractOperation_doOperation_test){
    inputs->push_back(cig->generate());

    criteria->push_back(io_width);
    criteria->push_back(io_height);
    criteria->push_back(io_sigmaX);

    outputs->push_back(io_out_img);

    BOOST_CHECK(out_img->size().width  == 0);
    BOOST_CHECK(out_img->size().height == 0);

    // Run the operation
    NAMESPACE::PipeStepComputation* psc = gbo;
    psc->doOperation(*inputs, *criteria, *outputs);

    // Check if the result of the operation is equal to the result of a
    // standard call to the wrapped function
    cv::Mat* in_img = boost::any_cast<cv::Mat*>( (*(inputs->begin()))->getElement() );
    cv::Mat tmp_out;
    int width = boost::any_cast<int>(io_width->getElement());
    int height = boost::any_cast<int>(io_height->getElement());
    double sigmaX = boost::any_cast<double>(io_sigmaX->getElement());
    cv::Size sz(width, height);
    cv::GaussianBlur(*in_img, tmp_out, sz, sigmaX);

    uchar* it = out_img->datastart;
    uchar* tmp_it = tmp_out.datastart;
    for(; it != out_img->dataend; it++, tmp_it++)
        BOOST_CHECK(*it == *tmp_it);
}

BOOST_AUTO_TEST_CASE(AbstractOperation_Constructors_test){
    inputs->push_back(cig->generate());

    criteria->push_back(io_width);
    criteria->push_back(io_height);
    criteria->push_back(io_sigmaX);

    outputs->push_back(io_out_img);

    gbo->doOperation(*inputs, *criteria, *outputs);

    copy_gbo = new NAMESPACE::GaussBlurOp(*gbo);
    BOOST_CHECK(*copy_gbo == *gbo);

    assigned_gbo = new NAMESPACE::GaussBlurOp();
    BOOST_CHECK(*assigned_gbo != *gbo);
    
    NAMESPACE::GaussBlurOp assigned_gbo2;
    assigned_gbo2 = *assigned_gbo = *gbo;
    BOOST_CHECK(*assigned_gbo == *gbo);
    BOOST_CHECK(assigned_gbo2 == *gbo);
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE_END()